package com.jhgk.jhcee.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jhgk.jhcee.common.constant.AuthConstant;
import com.jhgk.jhcee.common.domain.TableListModel;
import com.jhgk.jhcee.common.enums.BasisResultEnum;
import com.jhgk.jhcee.common.resultful.BasisResultful;
import com.jhgk.jhcee.common.service.RedisService;
import com.jhgk.jhcee.data.auth.entity.*;
import com.jhgk.jhcee.data.auth.mapper.*;
import com.jhgk.jhcee.system.domain.dao.SysResourceInfoDao;
import com.jhgk.jhcee.system.domain.model.*;
import com.jhgk.jhcee.system.service.SysResourceInfoService;
import com.jhgk.jhcee.system.service.SysRoleResourceRelationService;
import com.jhgk.jhcee.system.utils.TransitionUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: xiezhongping
 * @description:
 * @date: 2021/8/26 9:14.
 */
@Service(value = "SysResourceInfoServiceImpl")
public class SysResourceInfoServiceImpl extends ServiceImpl<SysResourceInfoMapper, SysResourceInfo> implements SysResourceInfoService {

    @Value("${spring.application.name}")
    private String applicationName;

    @Autowired
    SysResourceInfoMapper sysResourceInfoMapper;

    @Autowired
    SysRoleInfoMapper sysRoleInfoMapper;

    @Autowired
    SysRoleResourceRelationMapper sysRoleResourceMapper;

    @Autowired
    RedisService redisService;

    @Autowired
    SysResourceInfoDao sysResourceInfoDao;

    @Autowired
    SysModuleInfoMapper sysModuleInfoMapper;

    @Resource(name = "SysRoleResourceRelationServiceImpl")
    SysRoleResourceRelationService sysRoleResourceRelationService;

    @Override
    public Map<String, List<String>> initResourceRolesMap() {
        Map<String, List<String>> resourceRoleMap = new TreeMap<>();
        List<SysResourceInfo> resourceInfoList = sysResourceInfoMapper.selectList(null);
        List<SysRoleInfo> roleInfoList = sysRoleInfoMapper.selectList(null);
        List<SysRoleResourceRelation> roleResourceList = sysRoleResourceMapper.selectList(null);
        for (SysResourceInfo resourceInfo : resourceInfoList) {
            Set<Long> roleIds = roleResourceList.stream().filter(item -> item.getResourceId().equals(resourceInfo.getResourceId())).map(SysRoleResourceRelation::getRoleId).collect(Collectors.toSet());
            List<String> roleNames = roleInfoList.stream().filter(item -> roleIds.contains(item.getRoleId())).map(item -> item.getRoleId() + "_" + item.getRoleName()).collect(Collectors.toList());
            StringBuilder builder = new StringBuilder();
            builder.append("/");
            builder.append(applicationName);
            builder.append(resourceInfo.getResourcePath());
            resourceRoleMap.put(builder.toString(), roleNames);
        }
        redisService.del(AuthConstant.RESOURCE_ROLES_MAP_KEY);
        redisService.hSetAll(AuthConstant.RESOURCE_ROLES_MAP_KEY, resourceRoleMap);
        return resourceRoleMap;
    }

    @Override
    public BasisResultful<Object> getResourceListAll(SysResourceInfoModel model) {
        PageHelper.startPage(model.getPage(), model.getPageSize());
        List<SysResourceInfoModel> resourceDetailALl = sysResourceInfoDao.getResourceDetailALl(model);
        resourceDetailALl.forEach(resource -> {
            resource.setId(String.valueOf(resource.getResourceId()));
            resource.setRoleIds(sysRoleResourceMapper.selectListByResourceId(resource.getResourceId()));
        });
        PageInfo<SysResourceInfoModel> pageInfo = new PageInfo<>(resourceDetailALl);
        return BasisResultful.success(new TableListModel(pageInfo.getList(), pageInfo.getTotal()));
    }

    @Override
    public BasisResultful<Object> getModuleResource() {
        List<SysResourceInfo> sysResourceInfos = sysResourceInfoMapper.selectList(null);
        List<SysModuleInfo> sysModuleInfos = sysModuleInfoMapper.selectList(null);
        sysModuleInfos.sort(new SysModuleInfoComparator());
        List<SysModuleResourceModel> moduleResourceModels = new ArrayList<>();
        sysModuleInfos.stream().forEach(moduleInfo -> {
            SysModuleResourceModel model = setResourceType(moduleInfo, sysResourceInfos);
            moduleResourceModels.add(model);
        });
        moduleResourceModels.sort(new SysModuleResourceModelComparator());
        return BasisResultful.success(moduleResourceModels);
    }

    @Override
    public BasisResultful<Object> saveResource(SysResourceInfoModel model) {
        if (null == model) return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        this.save(model);
        return BasisResultful.success();
    }

    @Override
    public BasisResultful<Object> addResource(SysResourceInfoModel model) {
        if (null == model) {
            return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        }
        int insert = sysResourceInfoMapper.insert(model);
        if (insert <= 0) {
            return BasisResultful.fail();
        }
        // 新增关联关系
        Boolean aBoolean = sysRoleResourceRelationService.saveRoleResourceRelation(model.getRoleIds(), model.getResourceId());
        if (!aBoolean) return BasisResultful.fail();
        // 刷新缓存
        this.initResourceRolesMap();
        return BasisResultful.success();
    }

    @Override
    public BasisResultful<Object> deleteResource(SysResourceInfoModel model) {
        sysResourceInfoMapper.deleteById(model);
        // 删除关联关系
        Boolean aBoolean = sysRoleResourceRelationService.deleteResourceRelation(model.getResourceId());
        if (!aBoolean) return BasisResultful.fail();
        // 刷新缓存
        this.initResourceRolesMap();
        return BasisResultful.success();
    }

    @Override
    public BasisResultful<Object> updateResource(SysResourceInfoModel model) {
        if (null == model) return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        // 更新资源
        this.updateById(model);
        // 更新资源关联角色
        Boolean aBoolean = sysRoleResourceRelationService.saveRoleResourceRelation(model.getRoleIds(), model.getResourceId());
        if (!aBoolean) return BasisResultful.fail();
        // 刷新缓存
        this.initResourceRolesMap();
        return BasisResultful.success();
    }

    @Override
    public BasisResultful<Object> setResourceStatus(Long resourceId, Integer status) {
        if (null == resourceId || null == status) return BasisResultful.fail(BasisResultEnum.PARAM_IS_NULL);
        sysResourceInfoMapper.setResourceStatus(resourceId, status);
        return BasisResultful.success();
    }

    private SysModuleResourceModel setResourceType(SysModuleInfo moduleInfo, List<SysResourceInfo> resourceInfos) {
        List<SysResourceInfo> overResources = new ArrayList<>();
        resourceInfos.stream().forEach(resource -> {
            if (moduleInfo.getModuleId().equals(resource.getModuleId())) {
                overResources.add(resource);
            }
        });
        overResources.sort(new SysResourceInfoModelComparator());
        SysModuleResourceModel model = new SysModuleResourceModel();
        BeanUtil.copyProperties(moduleInfo, model);
        model.setResources(overResources);
        return model;
    }
}
